﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace VirtuOS
{
    class HashHandler
    {
        public static byte[] CreateSalt()
        {
            int minSaltSize = 4;
            int maxSaltSize = 8;

            Random r = new Random();
            int saltSize = r.Next(minSaltSize, maxSaltSize);
            byte[] salt = new byte[saltSize];

            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetNonZeroBytes(salt);
            return salt;
        }

        public static string ComputeHash(string input, string hashAlg, byte[] salt)
        {
            if (salt == null) { CreateSalt(); }

            byte[] plainTextBytes = Encoding.UTF8.GetBytes(input);
            byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + salt.Length];

            for (int i = 0; i < plainTextBytes.Length; i++)
                plainTextWithSaltBytes[i] = plainTextBytes[i];

            for (int i = 0; i < salt.Length; i++)
                plainTextWithSaltBytes[plainTextBytes.Length + i] = salt[i];

            HashAlgorithm hash;

            if (hashAlg == null)
                hashAlg = "";

            switch (hashAlg.ToUpper())
            {
                case "SHA1":
                    hash = new SHA1Managed();
                    break;

                case "SHA256":
                    hash = new SHA256Managed();
                    break;

                case "SHA384":
                    hash = new SHA384Managed();
                    break;

                case "SHA512":
                    hash = new SHA512Managed();
                    break;

                default:
                    hash = new MD5CryptoServiceProvider();
                    break;
            }

            byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
            byte[] hashWithSaltBytes = new byte[hashBytes.Length + salt.Length];

            for (int i = 0; i < hashBytes.Length; i++)
                hashWithSaltBytes[i] = hashBytes[i];

            for (int i = 0; i < salt.Length; i++)
                hashWithSaltBytes[hashBytes.Length + i] = salt[i];

            string hashValue = Convert.ToBase64String(hashWithSaltBytes);

            return hashValue;
        }
    }
}
